/********************************** (C) COPYRIGHT *******************************
 * File Name          : ch32v30x_it.c
 * Author             : WCH
 * Version            : V1.0.0
 * Date               : 2021/06/06
 * Description        : Main Interrupt Service Routines.
 *********************************************************************************
 * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
 * Attention: This software (modified or not) and binary are used for
 * microcontroller manufactured by Nanjing Qinheng Microelectronics.
 *******************************************************************************/
#include "ch32v30x_it.h"
#include "main.h"

void NMI_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void HardFault_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));

void TIM1_UP_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void EXTI4_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void EXTI9_5_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void SW_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
/*********************************************************************
 * @fn      NMI_Handler
 *
 * @brief   This function handles NMI exception.
 *
 * @return  none
 */
void NMI_Handler(void)
{
}

/*********************************************************************
 * @fn      HardFault_Handler
 *
 * @brief   This function handles Hard Fault exception.
 *
 * @return  none
 */
void HardFault_Handler(void)
{
    while (1)
    {
    }
}

void TIM1_UP_IRQHandler(void)
{
    // stepper_motor_controller.mcu->GpioSet(stepper_motor_controller.driver_board->param_pin_EMERGENCY.pin);
    if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)
    {
        // TIM1->INTFR = (uint16_t)~TIM_IT_Update;

        if ((TIM1->CTLR1 & TIM_DIR) == 0)
        {
            /* trigger adc sample */
            stepper_motor_controller.mcu->ADC_StartConversion();

            // if (stepper_motor_controller.timer_section_num == 0)
            // {
            //     stepper_motor_controller.mcu->GpioSet(stepper_motor_controller.driver_board->param_pin_EMERGENCY.pin);
            // }
            // else
            // {
            //     stepper_motor_controller.mcu->GpioToggle(stepper_motor_controller.driver_board->param_pin_EMERGENCY.pin);
            // }

            stepper_motor_controller.timer_section_num = (stepper_motor_controller.timer_section_num + 1) % (stepper_motor_controller.n_multiple_of_timmer_tick);

            if (stepper_motor_controller.timer_section_num == 0)
            {
                stepper_motor_controller.driver_board->TestGpio_Set(stepper_motor_controller.driver_board);
                // stepper_motor_controller.mcu->GpioToggle(stepper_motor_controller.driver_board->param_pin_EMERGENCY.pin);
            }
            stepper_motor_controller.TimTask(&stepper_motor_controller);
        }
        else
        {
        }
        TIM1->INTFR = (uint16_t)~TIM_IT_Update;
    }
    // stepper_motor_controller.mcu->GpioReset(stepper_motor_controller.driver_board->param_pin_EMERGENCY.pin);
}

void EXTI4_IRQHandler(void)
{
    if (EXTI_GetITStatus(EXTI_Line4) != RESET)
    {
        // EXTI_ClearITPendingBit(EXTI_Line4);

        // stepper_motor_controller.step_controller.Run(&stepper_motor_controller.step_controller);

        /* dir processing */
        stepper_motor_controller.step_controller.dir_pin_last = stepper_motor_controller.step_controller.dir_pin;
//        stepper_motor_controller.step_controller.dir_pin = stepper_motor_controller.mcu->GpioRead(stepper_motor_controller.driver_board->param_pin_DIR.pin);
        if (stepper_motor_controller.step_controller.param_pulse_trim_en != 0 &&
            stepper_motor_controller.step_controller.dir_pin != stepper_motor_controller.step_controller.dir_pin_last)
        {
            stepper_motor_controller.step_controller.dir_change = 2;
            // stepper_motor_controller.step_controller.pulse_on_dir_change = TIM_GetCounter(TIM4);
            stepper_motor_controller.step_controller.pulse_on_dir_change = TIM_GetCounter(TIM2);
        }

        if (stepper_motor_controller.step_controller.dir_pin != 0)
        {
            stepper_motor_controller.step_controller.dir = 1;
            // stepper_motor_controller.mcu->SetInputPulseCouterCountUp();

            TIM2->CTLR1 &= ~TIM_DIR;
        }
        else
        {
            stepper_motor_controller.step_controller.dir = -1;
            // stepper_motor_controller.mcu->SetInputPulseCouterCountDown();
            TIM2->CTLR1 |= TIM_DIR;
        }
        EXTI_ClearITPendingBit(EXTI_Line4);
    }
}

void EXTI9_5_IRQHandler(void)
{
    if (EXTI_GetITStatus(EXTI_Line8) != RESET)
    {
        // EXTI_ClearITPendingBit(EXTI_Line4);

        // stepper_motor_controller.step_controller.Run(&stepper_motor_controller.step_controller);

        /* dir processing */
        stepper_motor_controller.step_controller.dir_pin_last = stepper_motor_controller.step_controller.dir_pin;
//        stepper_motor_controller.step_controller.dir_pin = stepper_motor_controller.mcu->GpioRead(stepper_motor_controller.driver_board->param_pin_DIR.pin);
        if (stepper_motor_controller.step_controller.param_pulse_trim_en != 0 &&
            stepper_motor_controller.step_controller.dir_pin != stepper_motor_controller.step_controller.dir_pin_last)
        {
            stepper_motor_controller.step_controller.dir_change = 2;
            stepper_motor_controller.step_controller.pulse_on_dir_change = TIM_GetCounter(TIM3);
        }

        if (stepper_motor_controller.step_controller.dir_pin != 0)
        {
            stepper_motor_controller.step_controller.dir = 1;
            // stepper_motor_controller.mcu->SetInputPulseCouterCountUp();

            TIM3->CTLR1 &= ~TIM_DIR;
        }
        else
        {
            stepper_motor_controller.step_controller.dir = -1;
            // stepper_motor_controller.mcu->SetInputPulseCouterCountDown();
            TIM3->CTLR1 |= TIM_DIR;
        }
        EXTI_ClearITPendingBit(EXTI_Line8);
    }
}

/*********************************************************************
 * @fn      SW_Handler
 *
 * @brief   This function handles Software exception.
 *
 * @return  none
 */
void SW_Handler(void) {
    __asm("li  a6, 0x0000");
    __asm("jr  a6");

    while(1);
}

